package com.asa;

public class MartixTool {
    
    public static void main(String[] args) {
//        double[][] testData = new double [][] {
//            {1, 2, 3, 4}, 
//            {2, 3, 4, 1}, 
//            {3, 4, 1, 2}, 
//            {4, 1, 2, 3}
//        };
    	 double[][] testData = new double [][] {
             {1, 2}, 
             {2, 7}
         };
        double result = getValueBySubMartix(testData);
        System.out.println(result);//结果还要除以2
    }
    
    

    /**
     * get the Det value by sub martix : temp += aij * (-1) ^ (i + j) * det(Aij)
     * @param martix is a N X N type
     * @return
     */
    public static double getValueBySubMartix( double[][] martix ) {
        double result = 0D;
        int n = martix.length;
        if (n == 1) {
            return martix[0][0];
        }
        
        
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                
                double element = martix[i][j];
                
                int powNumber = i + j;//ignore + 2
                
                //construct a Aij
                double[][] subMartix = constructSubMartix(i, j, martix);
                
                
                
                
                result += element * Math.pow(-1, powNumber) * getValueBySubMartix(subMartix);
            }
        }
        
        return result;
    } 
    
    
    
    public static double[][] constructSubMartix(int rowIndex, int columnIndex, double[][] martix){
        int n = martix.length;
        if (n == 1) {
            return new double[][] {{martix[0][0]}};
        }
        
        //copy data
        double[][] clone = new double[n][n];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                clone[i][j] = martix[i][j];
            }
        }
        
        double[][] result = new double[n - 1][n - 1];
        // move row element when index great than or equals rowIndex 
        for(int i = rowIndex; i < n - 1; i++) {
            for(int j = 0; j < n; j++) {
                clone[i][j] = clone[i+1][j];
            }
        }
        // move column element when index great than or equals columnIndex
        for(int j = columnIndex; j < n - 1; j++) {
            for(int i = 0; i < n; i++) {
                clone[i][j] = clone[i][j+1];
            }
        }
        // copy element to result
        for(int i = 0; i < n - 1; i++) {
            for(int j = 0; j < n - 1; j++) {
                result[i][j] = clone[i][j];
            }
        }
        
        
        return result;
    }
}
